package util;

import runtime.TypeFactory;
import exception.ResultException;
import exception.TypeException;

public class Result {
	private Type type = null;
	private Object value = null;

	public Result(Type type, Object value) {
		this.type = type;
		this.value = value;
	}

	public Result(Reference var) {
		type = var.getType();
		value = var.getValue();
	}

	public Object getValue() {
		return value;
	}

	public void setValue(Object value) {
		if(value.getClass() == Result.class)
			throw new RuntimeException();
		this.value = value;
	}

	public Type getType() {
		return type;
	}

	public void setType(Type type) {
		this.type = type;
	}

	public boolean equals(Result result) throws ResultException {
		return compareTo(result) == 0;
	}

	public int compareTo(Result o) throws ResultException {
		TypeFactory tf = TypeFactory.getInstance();
		try {
			if (!this.getType().equals(o.getType())) {
				if (!((this.getType().equals(tf.getType("int")) || o.getType()
						.equals(tf.getType("int"))) && (this.getType().equals(
						tf.getType("double")) || o.getType().equals(
						tf.getType("double"))))) {

					if (!((this.getType().equals(tf.getType("string")) || o
							.getType().equals(tf.getType("string"))) && (this
							.getType().equals(tf.getType("char")) || o
							.getType().equals(tf.getType("char"))))) {
						throw new ResultException();
					}
				}

			}
			if (this.getType().equals(tf.getType("bool"))) {
				if (((Boolean) this.getValue()).equals(true)) {
					if (((Boolean) o.getValue()).equals(true)) {
						return 0;
					} else {
						return -1;
					}
				} else {
					if (((Boolean) o.getValue()).equals(true)) {
						return -1;
					} else {
						return 0;
					}
				}
			} else if (this.getType().equals(tf.getType("int"))
					|| this.getType().equals(tf.getType("double"))) {
				double left = 0D;
				if (this.getType().equals(tf.getType("int"))) {
					left = ((Integer) this.getValue()).doubleValue();
				} else {
					left = ((Double) this.getValue()).doubleValue();
				}
				double right = 0D;
				if (this.getType().equals(tf.getType("int"))) {
					right = ((Integer) this.getValue()).doubleValue();
				} else {
					right = ((Double) this.getValue()).doubleValue();
				}
				if (left < right) {
					return -1;
				}
				if (left > right) {
					return 1;
				}
				return 0;
			} else if (this.getType().equals(tf.getType("string"))
					|| this.getType().equals(tf.getType("char"))) {
				if (this.getValue().toString().compareTo(o.getValue().toString())<0) {
					return -1;
				} else if (this.getValue().toString().compareTo(o.getValue().toString())>0) {
					return 1;
				} else {
					return 0;
				}
			}
		} catch (TypeException e) {
			// olej
		}
		return 0;
	}
	
	public String toString() {
		return this.type+" "+this.value;
	}
}
